/**
 * @file appUser.c
 * @brief   
 * @author  xiaowine (xiaowine@sina.cn)
 * @version 01.00
 * @date    2021-04-07
 * 
 * @copyright Copyright (c) {2020}  xiaowine
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date       <th>Version <th>Author  <th>Description
 * <tr><td>2021-04-07 <td>1.0     <td>wangh     <td>内容
 * </table>
 * ******************************************************************
 * *                   .::::
 * *                 .::::::::
 * *                ::::::::::
 * *             ..:::::::::::
 * *          '::::::::::::
 * *            .:::::::::
 * *       '::::::::::::::..        女神助攻,流量冲天
 * *            ..::::::::::::.     永不宕机,代码无bug
 * *          ``:::::::::::::::
 * *           ::::``:::::::::'        .:::
 * *          ::::'   ':::::'       .::::::::
 * *        .::::'      ::::     .:::::::'::::
 * *       .:::'       :::::  .:::::::::' ':::::
 * *      .::'        :::::.:::::::::'      ':::::
 * *     .::'         ::::::::::::::'         ``::::
 * * ...:::           ::::::::::::'              ``::
 * *```` ':.          ':::::::::'                  ::::.
 * *                   '.:::::'                    ':'````.
 * ******************************************************************
 */
#include "appUser.h"
#include "stm32f0xx_hal.h"
#include <string.h>
#include "user_data.h"
#include "userLed.h"
/********************************************************************/
volatile _TKS_FLAGA_type keyTrg[2];
volatile unsigned char k_count[2];

#define keyNUM 3
#define RESTAIN_TIMES 200 // 200 × 10ms = 2s
unsigned char keyBeepMask[2] = {0xff, 0xff};
#define KEYMASK keyBeepMask[0]
#define RESTAINMASK keyBeepMask[1]
unsigned keyTime[keyNUM] = {0};
/*****beep***********************************************************/
_BEEP_STATE beepState = {0, 0, 0};
unsigned char beepCount = 1;
unsigned char beepLongCount = 0;
/********************************************************************/
volatile _TKS_FLAGA_type bitFlag;
volatile _TKS_FLAGA_type BLEbitFlag;
volatile _TKS_FLAGA_type I2CbitFlag;
volatile _TKS_FLAGA_type I2CboardFlag;
/********************************************************************/
const uint8_t protocolHeader[2] = {0xff, 0xa5};
/********************************************************************/
static void timerFlagOpt(void);
static void beepOpt(void);
static void keyScan(void);
static void i2cDataOpt(void);
static void refreshTxData(void);
/********************************************************************/

/**
 * @brief   
 * @param  argument         My Param doc
 */
void userProc(void const *argument)
{
    rgbInit();
    ledInit();
    for (;;)
    {
        timerFlagOpt();
        userRGB();
        beepOpt();
        keyScan();
        userLed();
        i2cDataOpt();
        osDelay(10);
    }
}

static void timerFlagOpt(void)
{
    FLAG_63MSF = TKS_63MSF;
    FLAG_250MSF = TKS_250MSF;
    FLAG_500MSF = TKS_500MSF;
    TKS_63MSF = 0;
    TKS_250MSF = 0;
    TKS_500MSF = 0;
}

static void beepOpt(void)
{
    if (BEEPMODE)
    {
        beepFlag = 1;
        // GPIOB->BRR = GPIO_PIN_8; // BEEP = BEEP_ON; // BEEP = BEEP_ON;
        beepCount = 0;
    }
    else
    {
        if (beepLongCount)
        {
            if (FLAG_500MSF)
            {
                if (beepFlag)
                {
                    beepFlag = 0;
                    // GPIOB->BSRR = GPIO_PIN_8; // BEEP = BEEP_OFF;
                    beepLongCount--;
                }
                else
                {
                    beepFlag = 1;
                    // GPIOB->BRR = GPIO_PIN_8; // BEEP = BEEP_ON;
                }
            }
            beepCount = 0;
            return;
        }
        if (FLAG_63MSF)
        {
            if (beepFlag)
            {
                beepFlag = 0;
                GPIOB->BRR = GPIO_PIN_8; // GPIOB->BSRR = GPIO_PIN_8; // BEEP = BEEP_OFF;
            }
            else if (beepCount)
            {
                beepCount--;
                beepFlag = 1;
                GPIOB->BSRR = GPIO_PIN_8; // GPIOB->BRR = GPIO_PIN_8; // BEEP = BEEP_ON;
            }
        }
    }
}
/**
 * @brief   
 */
static void keyScan(void)
{
    static uint8_t keyDataBak = 0;
    unsigned char keyRestain = 0, keyData, i;
    keyData = ((unsigned char)(GPIOB->IDR >> 3));
    keyData = (~keyData) & 0x07;

    if (keyData != keyDataBak)
    {
        keyDataBak = keyData;
        return;
    }

    keyTrg[0].byte = keyData & (keyData ^ k_count[0]);
    k_count[0] = keyData;
    if (keyTrg[0].byte & KEYMASK)
    {
        beepCount++;
    }

    for (i = 0; i < keyNUM; i++)
    {
        if (k_count[0] & (1 << i))
        {
            if (keyTime[i] < RESTAIN_TIMES)
                keyTime[i]++;
            else
                keyRestain |= (1 << i);
        }
        else
        {
            // if (keyTime[i] > 0)  // short press
            //     Key_Up_Trg |= (1 << i);
            // else
            //     Key_Up_Trg &= (~(1 << i));

            keyTime[i] = 0;
            keyRestain &= (~(1 << i));
        }
    }
    keyTrg[1].byte = keyRestain & (keyRestain ^ k_count[1]);
    k_count[1] = keyRestain;
    if (keyTrg[1].byte & RESTAINMASK)
    {
        beepCount++;
    }
}
#include "blePro.h"
static void i2cDataOpt(void)
{
    uint8_t checkSum, checkValue;
    if (I2CInOkFlag)
    {
        I2CInOkFlag = 0;
        if (memcmp(protocolHeader, (void *)I2cDataIn, 2) != 0)
        {
            return;
        }
        checkSum = getCheckSum((void *)I2cDataIn);
        checkValue = I2cDataIn[I2cDataIn[3] + 4];
        if (checkSum == checkValue)
        {
            switch (I2cDataIn[2])
            {
            case CMD_IDEL:
                break;
            case CMD_KEY:
                break;
            case CMD_LED:
                beepState.byte = I2cDataIn[4];
                ledState[0].byte = I2cDataIn[5];
                ledState[1].byte = I2cDataIn[6];
                if (BEEPMODE)
                {
                    beepCount = 0;
                    beepLongCount = 0;
                }
                else
                {
                    beepCount += BEEPSHORT;
                    beepLongCount += BEEPLONG;
                }
                break;
            case CMD_REG_UP:
                regDataOk = 1;
                memcpy((void *)bleTxBuff, (void *)I2cDataIn, 20);
                break;
            case CMD_REG_DOWN:
                break;
            case CMD_PARA:
                keyBeepMask[0] = I2cDataIn[4];
                keyBeepMask[1] = I2cDataIn[5];
                boardPARAFlag = 1;
                break;
            // case CMD_SEGMENT:
            //     memcpy(segmentValue, &I2cDataIn[4], 6);
            //     break;
            case CMD_RGBLEVEL:
                levelLedState = I2cDataIn[4];
                memcpy((void *)RGBRec, (void *)&I2cDataIn[5], 9);
                if (waterSrcLedState == STATE_LED_ON)
                    memcpy(&RGBState[0], &RGBRec[0], 3);
                if (waterOutLedState == STATE_LED_ON)
                    memcpy(&RGBState[1], &RGBRec[1], 3);
                if (heaterLedState == STATE_LED_ON)
                    memcpy(&RGBState[2], &RGBRec[2], 3);
                if (ledValue & 8)
                {
                    levelFlash(levelLedState, LED_OFF);
                }
                else
                {
                    levelFlash(levelLedState, LED_ON);
                }
                boardRGBFlag = 1;
                rgbNeedRefresh = 1;
                break;
            default:
                break;
            }
        }
    }
    refreshTxData();
}

static void refreshTxData(void)
{
    if (I2COutOkFlag)
    {
        I2COutOkFlag = 0;
        if (bleDataReday)
        {
            bleDataReday = 0;
            memcpy((void *)I2cDataOut, BleDataTemp, 20);
        }
        else
        {
            I2cDataOut[0] = 0xff;
            I2cDataOut[1] = 0xa5;
            I2cDataOut[2] = CMD_KEY;
            I2cDataOut[3] = 3;
            I2cDataOut[4] = I2CboardFlag.byte;
            I2cDataOut[5] = k_count[0];
            I2cDataOut[6] = k_count[1];
            I2cDataOut[7] = getCheckSum((void *)I2cDataOut);
        }
    }
}
